#ifndef FILE_Exception_HPP
#define FILE_Exception_HPP

#include <exception>
#include <sstream>
#include "Types.hpp"
// Credit for the Quoteme : Wikipedia.
#define QUOTEME_(x) #x
/********************************************//**
 * Quote the given macro content.
 *
 * Exemple :
 * \code
 * #define A BCD
 * QUOTEME(A) // -> "BCD"
 * \endcode
 ***********************************************/
#define QUOTEME(x) QUOTEME_(x)

/********************************************//**
 * Cause the program to crash to debugger.
 * 
 * Should be defined to a clean way to do it
 * following the compiler.
 * 
 * Currently a segfault, but maybe an assertion
 * would be cleaner.
 *
 * Think about the assert(exp) as a cleaner alternative.
 ***********************************************/
// TODO: think about the optimal way to do it.
#define SE_CRASH_TO_DEBUGGER {int* crash = NULL;*crash = 0;}

/// throw a simple-engine exception
#define SE_THROW(s) {\
                     std::stringstream ss;\
                     {ss<<s;}\
                     throw (se::Exception( __FILE__, (uint16_t)__LINE__, (ss.str()).c_str()));\
                     }


namespace se{

/********************************************//**
 * \brief The simple engine standard exception.
 * 
 * Thrown in simple engine modules. Should not be thrown in the
 * program using the simple engine. Note that for now, you don't have the
 * choice.
 * 
 * Its main advantage is the addition of the line and file.
 *
 * The drawback is : does not copy the file name (theorically, it is static)
 * and does not check for the \a what length before copying.
 *
 * Careful to what you feed.
 ***********************************************/
class Exception : std::exception {
	public:
		Exception(const char* fileName, uint16_t line, const char* what) throw();
		
		virtual const char* what() const throw();
		virtual const CodePosition where() const throw();
		
		virtual ~Exception() throw();
	protected:
		char m_what[1024];
		CodePosition m_where;
};

}//</namespace se>

#endif // FILE_Exception_HPP

